package com.md2ppt.cli;

import com.md2ppt.config.PresentationConfig;
import com.md2ppt.config.ConfigParser;
import com.md2ppt.engine.PresentationEngine;
import com.md2ppt.engine.EngineFactory;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Callable;

/**
 * MD2PPT Aspose.Slides CLI工具主入口
 * 使用JDK 17和现代Java特性
 */
@Command(
    name = "md2ppt-aspose-cli",
    version = "1.0.0",
    description = "MD2PPT Aspose.Slides Animation CLI Tool",
    mixinStandardHelpOptions = true
)
public class MD2PPTAsposeCLI implements Callable<Integer> {
    
    private static final Logger logger = LoggerFactory.getLogger(MD2PPTAsposeCLI.class);
    
    @Parameters(
        index = "0",
        description = "输入的JSON配置文件路径"
    )
    private File configFile;
    
    @Option(
        names = {"-o", "--output"},
        description = "输出PPTX文件路径",
        required = true
    )
    private File outputFile;
    
    @Option(
        names = {"-q", "--quality"},
        description = "动画质量级别: ${COMPLETION-CANDIDATES}",
        defaultValue = "NORMAL"
    )
    private QualityLevel quality;
    
    @Option(
        names = {"-t", "--timeout"},
        description = "处理超时时间（秒）",
        defaultValue = "300"
    )
    private int timeoutSeconds;
    
    @Option(
        names = {"-v", "--verbose"},
        description = "详细输出模式"
    )
    private boolean verbose;
    
    @Option(
        names = {"--dry-run"},
        description = "试运行模式，只验证配置不生成文件"
    )
    private boolean dryRun;
    
    public enum QualityLevel {
        LOW, NORMAL, HIGH
    }
    
    public static void main(String[] args) {
        int exitCode = new CommandLine(new MD2PPTAsposeCLI()).execute(args);
        System.exit(exitCode);
    }
    
    @Override
    public Integer call() throws Exception {
        configureLogging();
        
        try {
            logger.info("MD2PPT Aspose CLI 启动 - JDK {}", System.getProperty("java.version"));
            
            if (!validateInputs()) {
                return 1;
            }
            
            PresentationConfig config = parseConfiguration();
            if (config == null) {
                return 1;
            }
            
            if (dryRun) {
                logger.info("试运行模式：配置验证通过");
                return 0;
            }
            
            return processPresentation(config);
            
        } catch (Exception e) {
            logger.error("处理失败", e);
            return 1;
        }
    }
    
    private void configureLogging() {
        if (verbose) {
            System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "DEBUG");
        }
    }
    
    private boolean validateInputs() {
        if (!configFile.exists()) {
            logger.error("配置文件不存在: {}", configFile.getAbsolutePath());
            return false;
        }
        
        if (!configFile.canRead()) {
            logger.error("配置文件无法读取: {}", configFile.getAbsolutePath());
            return false;
        }
        
        File outputDir = outputFile.getParentFile();
        if (outputDir != null && !outputDir.exists()) {
            logger.info("创建输出目录: {}", outputDir.getAbsolutePath());
            if (!outputDir.mkdirs()) {
                logger.error("无法创建输出目录: {}", outputDir.getAbsolutePath());
                return false;
            }
        }
        
        return true;
    }
    
    private PresentationConfig parseConfiguration() {
        try {
            logger.info("解析配置文件: {}", configFile.getAbsolutePath());
            
            ConfigParser parser = new ConfigParser();
            PresentationConfig config = parser.parseFromFile(configFile.toPath());
            
            // 应用命令行参数覆盖
            applyCommandLineOverrides(config);
            
            logger.info("配置解析完成");
            if (verbose) {
                logger.debug("幻灯片数量: {}", config.getSlides().size());
                logger.debug("动画质量: {}", quality);
            }
            
            return config;
            
        } catch (Exception e) {
            logger.error("配置文件解析失败", e);
            return null;
        }
    }
    
    private void applyCommandLineOverrides(PresentationConfig config) {
        // Note: Records are immutable, so we log the override intent
        // The actual override should be done by creating new record instances
        // or by modifying the config before record creation
        
        if (verbose) {
            logger.debug("命令行质量设置: {}", quality.name());
            logger.debug("命令行超时设置: {}秒", timeoutSeconds);
            logger.debug("应用命令行参数覆盖完成");
        }
    }
    
    private int processPresentation(PresentationConfig config) {
        try {
            logger.info("开始处理演示文稿");
            
            // 获取最佳可用引擎
            PresentationEngine engine = getSelectedEngine(config);
            logger.info("使用引擎: {}", engine.getEngineName());
            
            // 显示引擎能力
            if (verbose) {
                logEngineCapabilities(engine);
            }
            
            long startTime = System.currentTimeMillis();
            
            // 生成演示文稿
            Path outputPath = outputFile.toPath();
            PresentationEngine.GenerationResult result = engine.generatePresentation(config, outputPath);
            
            long processingTime = System.currentTimeMillis() - startTime;
            
            if (result.success()) {
                logger.info("演示文稿处理完成");
                logger.info("输出文件: {}", outputPath.toAbsolutePath());
                logger.info("处理时间: {}ms", processingTime);
                
                if (verbose && result.statistics() != null) {
                    logGenerationStatistics(result.statistics());
                }
                
                return 0;
            } else {
                logger.error("演示文稿生成失败: {}", result.message());
                if (result.error() != null && verbose) {
                    logger.error("详细错误信息", result.error());
                }
                return 1;
            }
            
        } catch (Exception e) {
            logger.error("演示文稿处理失败", e);
            return 1;
        }
    }
    
    /**
     * 获取选定的引擎
     */
    private PresentationEngine getSelectedEngine(PresentationConfig config) {
        String engineName = config.settings().animationEngine();
        if (engineName != null) {
            return EngineFactory.getEngineByName(engineName);
        }
        return EngineFactory.getBestAvailableEngine();
    }
    
    /**
     * 记录引擎能力
     */
    private void logEngineCapabilities(PresentationEngine engine) {
        PresentationEngine.EngineCapabilities caps = engine.getCapabilities();
        logger.info("=== 引擎能力 ===");
        logger.info("支持动画: {}", caps.supportsAnimations());
        logger.info("支持高级效果: {}", caps.supportsAdvancedEffects());
        logger.info("支持视频嵌入: {}", caps.supportsVideoEmbedding());
        logger.info("支持自定义主题: {}", caps.supportsCustomThemes());
        if (caps.supportsAnimations()) {
            logger.info("最大动画效果数: {}", caps.maxAnimationEffects());
        }
    }
    
    /**
     * 记录生成统计
     */
    private void logGenerationStatistics(PresentationEngine.GenerationStatistics stats) {
        logger.info("=== 生成统计 ===");
        logger.info("幻灯片数: {}", stats.slidesGenerated());
        logger.info("动画效果数: {}", stats.animationsApplied());
        logger.info("处理时间: {}ms", stats.processingTimeMs());
        logger.info("文件大小: {} bytes", stats.fileSize());
    }
}